# -*- coding: utf-8 -*-
#

import threading

from sippeer.framework.sipsession.sipsession import SIPSession, SIPSessionCallback
from sippeer.utils.logutil import logger

from sippeer.libs.pjsip import pjsua as pj
from sippeer.framework.sipsession.siplib import lib

LOG_LEVEL=3
# Logging callback
def log_cb(level, str, len):
    print str,

class SIPAccountCallback(pj.AccountCallback):
    sem = None

    def __init__(self, account):
        pj.AccountCallback.__init__(self, account)

    def wait(self):
        self.sem = threading.Semaphore(0)
        self.sem.acquire()      
                
    def on_reg_state(self):
        """Notification that the registration status has changed.
        """
        if self.sem:
            if self.account.info().reg_status >= 200:
                self.sem.release()

    def on_incoming_call(self, call):
        """Notification about incoming call.

        Unless this callback is implemented, the default behavior is to
        reject the call with default status code.

        Keyword arguments:
        call    -- the new incoming call
        """
        call.hangup()

    def on_incoming_subscribe(self, buddy, from_uri, contact_uri, pres_obj):
        """Notification when incoming SUBSCRIBE request is received. 
        
        Application may use this callback to authorize the incoming 
        subscribe request (e.g. ask user permission if the request 
        should be granted)

        Keyword arguments:
        buddy       -- The buddy object, if buddy is found. Otherwise
                       the value is None.
        from_uri    -- The URI string of the sender.
        pres_obj    -- Opaque presence subscription object, which is
                       needed by Account.pres_notify()

        Return:
            Tuple (code, reason), where:
             code:      The status code. If code is >= 300, the
                        request is rejected. If code is 200, the
                        request is accepted and NOTIFY will be sent
                        automatically. If code is 202, application
                        must accept or reject the request later with
                        Account.press_notify().
             reason:    Optional reason phrase, or None to use the
                        default reasoh phrase for the status code.
        """
        return (200, None)

    def on_pager(self, from_uri, contact, mime_type, body):
        """
        Notification that incoming instant message is received on
        this account.

        Keyword arguments:
        from_uri   -- sender's URI
        contact    -- sender's Contact URI
        mime_type  -- MIME type of the instant message body
        body       -- the instant message body

        """
        pass

    def on_pager_status(self, to_uri, body, im_id, code, reason):
        """
        Notification about the delivery status of previously sent
        instant message.

        Keyword arguments:
        to_uri  -- the destination URI of the message
        body    -- the message body
        im_id   -- message ID
        code    -- SIP status code
        reason  -- SIP reason phrase

        """
        pass

    def on_typing(self, from_uri, contact, is_typing):
        """
        Notification that remote is typing or stop typing.

        Keyword arguments:
        buddy     -- Buddy object for the sender, if found. Otherwise
                     this will be None
        from_uri  -- sender's URI of the indication
        contact   -- sender's contact URI
        is_typing -- boolean to indicate whether remote is currently
                     typing an instant message.

        """
        pass



class SIPAccount:
    
    def __init__(self, id, password):
        
        # Init library with default config and some customized
        # logging config.
        self._account = None
        self._accountCallback = None
        self._transport = None
        self._id = id
        self._password = password 
        lib.init(log_cfg = pj.LogConfig(level=LOG_LEVEL, callback=log_cb))
    

        
    def config(self, server, port):
        self._server = server
        self._port = port
        # Create UDP transport which listens to any available port
        self._transport = lib.create_transport(pj.TransportType.UDP, 
                                         pj.TransportConfig(port))
        print "\nListening on", self._transport.info().host, 
        print "port", self._transport.info().port, "\n"
        
        
    def start(self):
        
        # Start the library
        lib.start()
        
        self._account = lib.create_account(pj.AccountConfig(self._server, self._id, self._password))

        self._accoutCallback = SIPAccountCallback(self._account)
        self._account.set_callback(self._accoutCallback)
        self._accoutCallback.wait()
        
    def startNewSession(self, uri):
        
        lck = lib.auto_lock()
        current_call = make_call(uri, SIPSessionCallback())
                
        print 'Current call is', current_call
        del lck
        
        new_session = SIPSession(current_call)
        
       # SIPSessionPool.getInstance().addSIPSession(new_session)

    
